package eu.scillman.net.udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import eu.scillman.interfaces.ICommConstants;
import eu.scillman.net.Member;

public abstract class ConnectionBase {

	/**
	 * The UDP socket.
	 */
	private DatagramSocket socket;
	
	/**
	 * Initialize the UDP socket.
	 */
	{
		try {
			socket = getSocket();
			socket.setSoTimeout(ICommConstants.CONNECTION_TIMEOUT);
		} catch (Exception ex) {
			System.out.println("Could not create an asynchronous socket; abandoning connection.");
			disconnect();
		}
	}
	
	public ConnectionBase() {
		// Do something...
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void finalize() throws Throwable {
		disconnect();
		super.finalize();
	}
	
	/**
	 * Get the socket for the UDP connection.
	 * @return The default socket for the connection.
	 */
	protected abstract DatagramSocket getSocket() throws SocketException;
	
	/**
	 * Disconnect the socket.
	 */
	protected void disconnect() {
		if (socket != null) {
			if (!socket.isClosed()) {
				socket.close();
			}
			socket = null;
		}
	}
	
	/**
	 * Receive data from the remote device.
	 * @return The data received from the remote device.
	 */
	protected byte[] receive() {
		byte[] data = new byte[ICommConstants.BUFFER_SIZE];
		DatagramPacket packet = new DatagramPacket(data, data.length);
		try {
			socket.receive(packet);
		} catch (Exception ex) {
			System.out.println("Unable to receive packet from remote device!");
		}
		
		return data;
	}
	
	/**
	 * Send data to a remote device.
	 * @param data The data that has to be send to the remote device.
	 * @param client The client that is meant to receive the data.
	 */
	protected void send(byte[] data, Member client) {
		DatagramPacket packet = new DatagramPacket(data, data.length, client.getAddress(), client.getPort());
		try {
			socket.send(packet);
		} catch (Exception ex) {
			System.out.println("Unable to send packet to remote device with address: " + client.toString());
		}
	}
}
